//
//  ViewController.swift
//  DemoUI
//  模板默认创建的是一个试图文件
//  Created by 白瑾浩 on 2022/1/5.
//

import UIKit
import SwiftUI

class ViewController: UIViewController, MVCViewControllerProtocol {
    fileprivate let formatter: DateFormatter = {
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd"
        return formatter
    }()
    var _results: [String] = []
    var mUIScrollView:UIScrollView?
    func sentData(data: String) {
        print( "上一页传递的值为：\(data)" )
    }
    func doSomething(completionHandler: ((String) -> Void)? = nil) {
        print("test1")
    }
    
    func doSomething() async -> String {
        print("test2")
        return ""
    }
    
    //到一分钟提示框
    var continueButtonAction:String = ""
    var uiAlertAction:UIAlertAction?
    var uiAlertController:UIAlertController?
    
    //@IBOutlet 对应的界面元素在 loadView() 才会被加载
    @IBOutlet weak var button1:UIButton?
    //加载视图完成时调用
    override func viewDidLoad() {
        super.viewDidLoad()
        title = "测试demo"
        ///let time = "2022-05-01T22:00:00+08:00"
        print(timeFormat(time:  "2022-05-01T22:00:00+08:00" ))
        navigationController?.isNavigationBarHidden = false
        mUIScrollView = UIScrollView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height))
        self.view.addSubview( mUIScrollView! )
        mUIScrollView?.contentSize = CGSize(width:  UIScreen.main.bounds.width, height: UIScreen.main.bounds.height*3)
        
        print( "加载视图完成时调用" )
        
        let arrSplit = [1,2,3,4,5,6,7,8,9,10,11]
        
        var i = 0
        
        while i < arrSplit.count{
            
            let endi =   i + 5 >= arrSplit.count ? arrSplit.count : i + 5
            
            let info = Array( arrSplit[i..<endi] )
            
            for j in 0..<info.count{
                print( info[j])
            }
            
            i = i+5
        }
        
        i = 0
        
        while i < arrSplit.count{
            
            let count =   i + 5 >= arrSplit.count ? arrSplit.count - i  : 5
            
            for j in 0..<count{
                print( arrSplit[i+j] )
            }
            i = i+5
        }
        
        
        a()
        data()
        
        dispatch_async_demo()
        //        myFunction()
        //
        someSyncMethod()
        //
        //
        //        doSomething()      // print test1
        //
        //           async {
        //               await doSomething()  // print test2
        //           }
        //
        //
        Task{
            await download()
            await printNews()
        }
        
        test()
        
        
        self.view.backgroundColor = .white
        
        // Do any additional setup after loading the view.
        let button0 = UIButton(type: UIButton.ButtonType.system)
        button0.frame = CGRect(x: 10, y: 50, width: 150, height: 30)
        button0.setTitle("uilabtext", for: UIControl.State.normal)
        button0.addTarget(self, action: #selector(JumpUILableViewControl(_:)), for: .touchUpInside)
        self.mUIScrollView?.addSubview( button0 )
        
        
        let button00 = UIButton(type: UIButton.ButtonType.system)
        button00.frame = CGRect(x: 200, y: 50, width: 250, height: 30)
        button00.setTitle("活动指示器控件", for: UIControl.State.normal)
        button00.addTarget(self, action: #selector(JumpUIActivityIndicatorView(_:)), for: .touchUpInside)
        self.mUIScrollView?.addSubview( button00 )
        
        //UIbutton
        //        UIButtonType.system：前面不带图标，默认文字颜色为蓝色，有触摸时的高亮效果
        //        UIButtonType.custom：定制按钮，前面不带图标，默认文字颜色为白色，无触摸时的高亮效果
        //        UIButtonType.contactAdd：前面带“+”图标按钮，默认文字颜色为蓝色，有触摸时的高亮效果
        //        UIButtonType.detailDisclosure：前面带“!”图标按钮，默认文字颜色为蓝色，有触摸时的高亮效果
        //        UIButtonType.infoDark：为感叹号“!”圆形按钮
        //        UIButtonType.infoLight：为感叹号“!”圆形按钮
        //let button1 = UIButton(type: UIButton.ButtonType.system)
        let button1 = UIButton(type: UIButton.ButtonType.infoDark)
        button1.frame = CGRect(x: 10, y: 100, width: 150, height: 30)
        button1.backgroundColor = UIColor.purple
        button1.setTitle("UITextField", for: UIControl.State.normal)
        button1.setTitleColor(UIColor.white, for: .normal)
        button1.titleLabel?.font = UIFont.systemFont(ofSize: 11)
        //button1.layer.cornerRadius = 8
        //button1.layer.masksToBounds = true
        button1.layer.cornerRadius = 8.0//2.0是圆角的弧度，根据需求自己更改
        button1.layer.borderColor = UIColor.red.cgColor//设置边框颜色
        button1.layer.borderWidth = 2.0 //设置边框颜色
        button1.addTarget(self, action: #selector(highlightBorder(_:)), for: .touchDown)
        button1.addTarget(self, action: #selector(normalBorder(_:)), for: .touchUpInside)
        
        //button1.addTarget(self, action:#selector(tapped(_:)), for:.touchUpInside)
        
        
        //设置图片
        //        button.setImage(UIImage(named:"icon1"),forState:.Normal)  //设置图标
        //        button.adjustsImageWhenHighlighted=false //使触摸模式下按钮也不会变暗（半透明）
        //        button.adjustsImageWhenDisabled=false //使禁用模式下按钮也不会变暗（半透明）
        //
        //button.setBackgroundImage(UIImage(named:"bg1"), for:.normal)
        self.mUIScrollView?.addSubview( button1 )
        
        //        self.view.backgroundColor = UIColor(normal: "ffffff") //黑夜模式与正常颜色通用 透明度 1
        //        self.view.backgroundColor = UIColor(normal: "ffffff", dark: "000000") //黑夜模式下 黑色  正常：白色 透明度 1
        //        self.view.backgroundColor = UIColor(normal: "ffffff", dark: "000000", alpha: 0.5) //黑夜模式下 黑色  正常：白色 透明度均为 0.5
        //        self.view.backgroundColor = UIColor(normal: "ffffff", normalAlpha: 0.5, dark: "000000", darkAlpha: 1) //黑夜模式下 黑色  正常：白色  透明度 黑夜：1  正常：0.5
        //
        
        let button9 = UIButton(type: UIButton.ButtonType.infoDark)
        button9.frame = CGRect(x: 200, y: 100, width: 150, height: 30)
        button9.backgroundColor = UIColor.purple
        button9.setTitle("UISwitch", for: UIControl.State.normal)
        button9.setTitleColor(UIColor.white, for: .normal)
        button9.titleLabel?.font = UIFont.systemFont(ofSize: 11)
        //button1.layer.cornerRadius = 8
        //button1.layer.masksToBounds = true
        button9.layer.cornerRadius = 8.0//2.0是圆角的弧度，根据需求自己更改
        button9.layer.borderColor = UIColor.red.cgColor//设置边框颜色
        button9.layer.borderWidth = 2.0 //设置边框颜色
        button9.addTarget(self, action: #selector(FuncUISwitch(_:)), for: .touchUpInside)
        self.mUIScrollView?.addSubview( button9 )
        
        //button图片设置
        let button2 = UIButton(type:UIButton.ButtonType.custom)
        button2.frame = CGRect(x: 10, y: 200-50, width: 150, height: 30)
        button2.setImage(UIImage(named: "button"), for: UIControl.State.normal )
        button2.setTitle("点击", for: .normal)
        button2.setBackgroundImage(UIImage(named: "ic_launcher"), for: .normal)
        self.mUIScrollView?.addSubview( button2 )
        
        
        
        let button10 = UIButton(type: UIButton.ButtonType.infoDark)
        button10.frame = CGRect(x: 200, y: 200-50, width: 150, height: 30)
        button10.backgroundColor = UIColor.purple
        button10.setTitle("UIPageControl", for: UIControl.State.normal)
        button10.setTitleColor(UIColor.white, for: .normal)
        button10.titleLabel?.font = UIFont.systemFont(ofSize: 11)
        //button1.layer.cornerRadius = 8
        //button1.layer.masksToBounds = true
        button10.layer.cornerRadius = 8.0//2.0是圆角的弧度，根据需求自己更改
        button10.layer.borderColor = UIColor.red.cgColor//设置边框颜色
        button10.layer.borderWidth = 2.0 //设置边框颜色
        button10.addTarget(self, action: #selector(FuncUIPageControl(_:)), for: .touchUpInside)
        self.mUIScrollView?.addSubview( button10 )
        
        
        let button11 = UIButton(type: UIButton.ButtonType.infoDark)
        button11.frame = CGRect(x: 10, y: 240-50, width: 150, height: 30)
        button11.backgroundColor = UIColor.purple
        button11.setTitle("slider", for: UIControl.State.normal)
        button11.setTitleColor(UIColor.white, for: .normal)
        button11.titleLabel?.font = UIFont.systemFont(ofSize: 11)
        //button1.layer.cornerRadius = 8
        //button1.layer.masksToBounds = true
        button11.layer.cornerRadius = 8.0//2.0是圆角的弧度，根据需求自己更改
        button11.layer.borderColor = UIColor.red.cgColor//设置边框颜色
        button11.layer.borderWidth = 2.0 //设置边框颜色
        button11.addTarget(self, action: #selector(UIInteractionControl(_:)), for: .touchUpInside)
        self.mUIScrollView?.addSubview( button11 )
        
        
        // Do any additional setup after loading the view.
        let button12 = UIButton(type: UIButton.ButtonType.system)
        button12.frame = CGRect(x: 10, y: 300-50, width: 150, height: 30)
        button12.setTitle("搜索", for: UIControl.State.normal)
        button12.addTarget(self, action: #selector(JumpSearchViewControl), for: .touchUpInside)
        self.mUIScrollView?.addSubview( button12 )
        
        
        let button13 = UIButton(type: UIButton.ButtonType.system)
        button13.frame = CGRect(x: 200, y: 300-50, width: 150, height: 30)
        button13.setTitle("协议传值跳转", for: UIControl.State.normal)
        button13.addTarget(self, action: #selector(JumpProtocolViewControl), for: .touchUpInside)
        self.mUIScrollView?.addSubview( button13 )
        
        
        let button14 = UIButton(type: UIButton.ButtonType.system)
        button14.frame = CGRect(x: 10, y: 350-50, width: 150, height: 30)
        button14.setTitle("闭包传值跳转", for: UIControl.State.normal)
        button14.addTarget(self, action: #selector(JumpClosureFuncViewControl), for: .touchUpInside)
        self.mUIScrollView?.addSubview( button14 )
        
        let button15 = UIButton(type: UIButton.ButtonType.system)
        button15.frame = CGRect(x: 200, y: 350-50, width: 150, height: 30)
        button15.setTitle("uiswitch", for: UIControl.State.normal)
        button15.addTarget(self, action: #selector(JumpUISwitchViewControl), for: .touchUpInside)
        self.mUIScrollView?.addSubview( button15 )
        
        //uinavgation 导航试图控制
        let button16 = UIButton(type: UIButton.ButtonType.system)
        button16.frame = CGRect(x: 10, y: 400-50, width: 150, height: 30)
        button16.setTitle("uiNavgation", for: UIControl.State.normal)
        button16.addTarget(self, action: #selector(JumpUINavigationViewControl), for: .touchUpInside)
        self.mUIScrollView?.addSubview( button16 )
        
        //标签栏控制器
        let button17 = UIButton(type: UIButton.ButtonType.system)
        button17.frame = CGRect(x: 200, y: 400-50, width: 150, height: 30)
        button17.setTitle("UITabBarController", for: UIControl.State.normal)
        button17.addTarget(self, action: #selector(JumpUITabBarController), for: .touchUpInside)
        self.mUIScrollView?.addSubview( button17 )
        
        //警告弹窗
        let button18 = UIButton(type: UIButton.ButtonType.system)
        button18.frame = CGRect(x: 10, y: 450-50, width: 150, height: 30)
        button18.setTitle("警告弹窗", for: UIControl.State.normal)
        button18.addTarget(self, action: #selector(JumpAlertViewController), for: .touchUpInside)
        self.mUIScrollView?.addSubview( button18 )
        
        //网页视图应用
        //webview
        let button19 = UIButton(type: UIButton.ButtonType.system)
        button19.frame = CGRect(x: 200, y: 450-50, width: 150, height: 30)
        button19.setTitle("网页视图应用", for: UIControl.State.normal)
        button19.addTarget(self, action: #selector(JumpWebviewViewController), for: .touchUpInside)
        self.mUIScrollView?.addSubview( button19 )
        //wkwebview
        let button20 = UIButton(type: UIButton.ButtonType.system)
        button20.frame = CGRect(x: 0, y: 500-50, width: 150, height: 30)
        button20.setTitle("网页视图应用2", for: UIControl.State.normal)
        button20.addTarget(self, action: #selector(JumpWKWebviewViewController), for: .touchUpInside)
        self.mUIScrollView?.addSubview( button20 )
        
        //UIScrollView
        let button21 = UIButton(type: UIButton.ButtonType.system)
        button21.frame = CGRect(x: 200, y: 500-50, width: 150, height: 30)
        button21.setTitle("UIScrollView", for: UIControl.State.normal)
        button21.addTarget(self, action: #selector(JumpUIScrollViewController), for: .touchUpInside)
        self.mUIScrollView?.addSubview( button21 )
        
        //TableViewController
        let button22 = UIButton(type: UIButton.ButtonType.system)
        button22.frame = CGRect(x: 0, y: 550-50, width: 150, height: 30)
        button22.setTitle("UITableView", for: UIControl.State.normal)
        button22.addTarget(self, action: #selector(JumpTableViewController), for: .touchUpInside)
        self.mUIScrollView?.addSubview( button22 )
        
        let button23 = UIButton(type: UIButton.ButtonType.system)
        button23.frame = CGRect(x: 200, y: 550-50, width: 150, height: 30)
        button23.setTitle("UITableViewGroup", for: UIControl.State.normal)
        button23.addTarget(self, action: #selector(JumpTableViewGroupController), for: .touchUpInside)
        self.mUIScrollView?.addSubview( button23 )
        
        
        let button24 = UIButton(type: UIButton.ButtonType.system)
        button24.frame = CGRect(x: 0, y: 600-50, width: 150, height: 30)
        button24.setTitle("UITableViewXIBGroup", for: UIControl.State.normal)
        button24.addTarget(self, action: #selector(JumpTableUIViewXIBDataController), for: .touchUpInside)
        self.mUIScrollView?.addSubview( button24 )
        
        
        let button25 = UIButton(type: UIButton.ButtonType.system)
        button25.frame = CGRect(x: 200, y: 600-50, width: 150, height: 30)
        button25.setTitle("UICollectionView", for: UIControl.State.normal)
        button25.addTarget(self, action: #selector(JumpUICollectionViewController), for: .touchUpInside)
        self.mUIScrollView?.addSubview( button25 )
        
        
        let button26 = UIButton(type: UIButton.ButtonType.system)
        button26.frame = CGRect(x: 0, y: 650-50, width: 150, height: 30)
        button26.setTitle("animation", for: UIControl.State.normal)
        button26.addTarget(self, action: #selector(JumpUIAnimationViewController), for: .touchUpInside)
        self.mUIScrollView?.addSubview( button26 )
        
        
        let button27 = UIButton(type: UIButton.ButtonType.system)
        button27.frame = CGRect(x: 200, y: 650-50, width: 150, height: 30)
        button27.setTitle("GIF", for: UIControl.State.normal)
        button27.addTarget(self, action: #selector(JumpUIGifViewController), for: .touchUpInside)
        self.mUIScrollView?.addSubview( button27 )
        
        
        let button28 = UIButton(type: UIButton.ButtonType.system)
        button28.frame = CGRect(x: 10, y: 680-50, width: 150, height: 30)
        button28.setTitle("coreAnimation", for: UIControl.State.normal)
        button28.addTarget(self, action: #selector(JumpCoreAnimationViewController), for: .touchUpInside)
        self.mUIScrollView?.addSubview( button28 )
        
        
        let button29 = UIButton(type: UIButton.ButtonType.system)
        button29.frame = CGRect(x: 200, y: 680-50, width: 150, height: 30)
        button29.setTitle("uiautolayout2", for: UIControl.State.normal)
        button29.addTarget(self, action: #selector(JumpAutoLayoutViewController), for: .touchUpInside)
        self.mUIScrollView?.addSubview( button29 )
        
        
        let button30 = UIButton(type: UIButton.ButtonType.system)
        button30.frame = CGRect(x: 0, y: 710-50, width: 150, height: 30)
        button30.setTitle("uiautolayout0", for: UIControl.State.normal)
        button30.addTarget(self, action: #selector(JumpAutoLayout0ViewController), for: .touchUpInside)
        self.mUIScrollView?.addSubview( button30 )
        
        
        let button31 = UIButton(type: UIButton.ButtonType.system)
        button31.frame = CGRect(x: 200, y: 710-50, width: 150, height: 30)
        button31.setTitle("SnapKit", for: UIControl.State.normal)
        button31.addTarget(self, action: #selector(JumpSnapKitViewController), for: .touchUpInside)
        self.mUIScrollView?.addSubview( button31 )
        
        let button32 = UIButton(type: UIButton.ButtonType.system)
        button32.frame = CGRect(x: 0, y: 750-50, width: 150, height: 30)
        button32.setTitle("线程", for: UIControl.State.normal)
        button32.addTarget(self, action: #selector(JumpSnapKitViewController2), for: .touchUpInside)
        self.mUIScrollView?.addSubview( button32 )
        
        let button33 = UIButton(type: UIButton.ButtonType.system)
        button33.frame = CGRect(x: 200, y: 750-50, width: 150, height: 30)
        button33.setTitle("其他UI实例", for: UIControl.State.normal)
        button33.addTarget(self, action: #selector(JumpSnapKitViewController3), for: .touchUpInside)
        self.mUIScrollView?.addSubview( button33 )
        
        
        let button34 = UIButton(type: UIButton.ButtonType.system)
        button34.frame = CGRect(x: 0, y: 780-50, width: 150, height: 30)
        button34.setTitle("播放pcm文件", for: UIControl.State.normal)
        button34.addTarget(self, action: #selector(JumpSnapKitViewController34), for: .touchUpInside)
        self.mUIScrollView?.addSubview( button34 )
        
        let button35 = UIButton(type: UIButton.ButtonType.system)
        button35.frame = CGRect(x: 200, y: 780-50, width: 150, height: 30)
        button35.setTitle("歌词", for: UIControl.State.normal)
        button35.addTarget(self, action: #selector(JumpSnapKitViewController35), for: .touchUpInside)
        self.mUIScrollView?.addSubview( button35 )
        
        
        let button36 = UIButton(type: UIButton.ButtonType.system)
        button36.frame = CGRect(x: 0, y: 810-50, width: 150, height: 30)
        button36.setTitle("背景设置", for: UIControl.State.normal)
        button36.addTarget(self, action: #selector(bgSetting), for: .touchUpInside)
        self.mUIScrollView?.addSubview( button36 )
        
        let button37 = UIButton(type: UIButton.ButtonType.system)
        button37.frame = CGRect(x: 200, y: 810-50, width: 150, height: 30)
        button37.setTitle("自定义弹框", for: UIControl.State.normal)
        button37.addTarget(self, action: #selector(alertDialog), for: .touchUpInside)
        self.mUIScrollView?.addSubview( button37 )
        
        
        let button38 = UIButton(type: UIButton.ButtonType.system)
        button38.frame = CGRect(x: 0, y: 840-50, width: 150, height: 30)
        button38.setTitle("跳转到swiftUI", for: UIControl.State.normal)
        button38.addTarget(self, action: #selector(jumpSwiftui), for: .touchUpInside)
        self.mUIScrollView?.addSubview( button38 )
        
        
        
        //operationQueue()
        operationqueue()
        
        
        
        
        NotificationCenter.default.addObserver(self,
                                               selector: #selector(deleteOlderFiles as () -> Void),
                                               name: UIApplication.willTerminateNotification, //
                                               object: nil)
        NotificationCenter.default.addObserver(self,
                                               selector: #selector(backgroundDeleteOldFiles),
                                               name: UIApplication.didEnterBackgroundNotification,//程序在后台执行
                                               object: nil)
        
        
        
        
        
    }
    var mQAAudioUnitPlayer:QAAudioUnitPlayer?
    
    var file : UnsafeMutablePointer<FILE>?
    var pcmDataBuffer:UnsafeMutableRawPointer?
    var time2:Timer?
    var data3 = Data()
    //播放音乐pcm 文件
    @objc func JumpSnapKitViewController34(){
        setupAudioSession()
        if mQAAudioUnitPlayer != nil{
            mQAAudioUnitPlayer?.stopPlay()
            mQAAudioUnitPlayer = nil
        }
        mQAAudioUnitPlayer = QAAudioUnitPlayer.init()
        mQAAudioUnitPlayer?.startPlay()
        let settingsBundlePath = Bundle.main.path(forResource: "ios_sound", ofType: "pcm")
        if settingsBundlePath == nil {
            print( "获取路径错误" )
        }
        print( settingsBundlePath! )
        let readHandler = FileHandle(forReadingAtPath: settingsBundlePath! )
        data3 = readHandler?.readDataToEndOfFile() ?? Data()
        print( "data=\(data3.count)" )
        if data3 != nil && data3.count > 0 {
            //获取数据
            print( " 111111  ")
        }
        //播放文件pcm
        //mQAAudioUnitPlayer?.addAudioData(data: data3 )
        time2 = Timer.scheduledTimer(timeInterval: 1/40, target:self, selector: #selector(timerTest), userInfo: nil, repeats: true)
        
        
        
    }
    private var backgroundTaskId: UIBackgroundTaskIdentifier = UIBackgroundTaskIdentifier.invalid  //无效的
    
    @objc func deleteOlderFiles(){
        
        print( "进入终止调用" )
    }
    //    App进入后台，（绝大部分情况下）会暂停执行代码，进入挂起状态。 有时候，某个任务进入后台后，我们希望它完成任务后再挂起。可以用UIBackgroundTaskIdentifier标记该任务，任务结束后再结束标记。标记之后的任务，在执行的时候，即使App进入后台，也会执行完成（大约有不超过10分钟的时间）后再挂起App。
    @objc func backgroundDeleteOldFiles(){
        print( "进入后台调用" )
        //开始标记为支持后台执行
        backgroundTaskId = UIApplication.shared.beginBackgroundTask(expirationHandler: { [weak self] in
            // 超过10分钟后（一般是3分钟），会进入到这里
            print( "进入后台调用=======" )
            guard let strongSelf = self else { return }
            UIApplication.shared.endBackgroundTask(strongSelf.backgroundTaskId)
            strongSelf.backgroundTaskId = .invalid
            print( "进入后台调用2" )
        })
        
        //长时间执行任务，（进入后台后，大约有10分钟的执行时间，超过之后程序会挂起）
        //do something
        
        //*****
        //*****
        //*****
        
        //结束标记
        if self.backgroundTaskId != .invalid {
            print( "进入后台调用3" )
            UIApplication.shared.endBackgroundTask(self.backgroundTaskId)
            self.backgroundTaskId = .invalid
        }else{
            print( "进入后台调用4" )
        }
    }
    
    
    deinit {
        NotificationCenter.default.removeObserver(self)
    }
    var index = 0
    @objc func timerTest(){
        if (index+1) * 640 > data3.count {
            return
        }
        
        let datas = data3.subdata(in: index * 640 ..< (index+1)*640 )
        
        mQAAudioUnitPlayer?.addAudioData(data: datas )
        
        index = index + 1
        
    }
    @objc func JumpSnapKitViewController35(){
        
        self.navigationController?.pushViewController(Music(), animated: true)
        
    }
    
    //背景设置
    @objc func bgSetting(){
        
        self.navigationController?.pushViewController(BackgroundController(), animated: true)
        
        
        
    }
    
    
    
    @objc func JumpSnapKitViewController3(){
        self.navigationController?.pushViewController(DemoController(), animated: true)
    }
    
    @objc func JumpSnapKitViewController2(){
        self.navigationController?.pushViewController(asyncController(), animated: true)
    }
    
    @IBAction @objc func  JumpSnapKitViewController(){
        self.navigationController?.pushViewController(SnapKitViewController(), animated: true)
    }
    
    @IBAction @objc func  JumpAutoLayout0ViewController(){
        self.navigationController?.pushViewController(AutoLayoutViewController(), animated: true)
    }
    
    @IBAction @objc func  JumpAutoLayoutViewController(){
        self.navigationController?.pushViewController(AutoLayout2ViewController(), animated: true)
    }
    @IBAction @objc func  JumpCoreAnimationViewController(){
        self.navigationController?.pushViewController(CoreAnimationViewController(), animated: true)
    }
    
    //gif播放
    @IBAction @objc func JumpUIGifViewController(){
        self.navigationController?.pushViewController(GifViewController(), animated: true)
    }
    
    //动画
    @IBAction  @objc func JumpUIAnimationViewController(){
        self.navigationController?.pushViewController(UIAnimationViewController(), animated: true)
    }
    
    //9宫格布局
    @IBAction @objc func JumpUICollectionViewController(){
        self.navigationController?.pushViewController( UICollectionViewController(), animated: true )
    }
    //实例
    @IBAction @objc func JumpTableUIViewXIBDataController(){
        self.navigationController?.pushViewController(TableUIViewDataController(), animated: true)
    }
    
    //UITableView
    @IBAction @objc func JumpTableViewController(){
        self.navigationController?.pushViewController(TableUIViewController(), animated: true)
    }
    //UITableViewGroup
    @IBAction @objc func JumpTableViewGroupController(){
        self.navigationController?.pushViewController(TableUIViewGroupController(), animated: true)
    }
    //滚动试图
    @IBAction @objc func JumpUIScrollViewController(){
        
        self.navigationController?.pushViewController(ScrollViewController(), animated: true)
    }
    
    //网页视图应用JumpWKWebviewViewController
    @IBAction @objc func JumpWKWebviewViewController(){
        self.navigationController?.pushViewController(WKWebViewController(), animated: true)
    }
    
    //网页视图应用
    @IBAction @objc func JumpWebviewViewController(){
        self.navigationController?.pushViewController(WebViewViewController(), animated: true)
    }
    
    //警告弹窗
    @objc func JumpAlertViewController(){
        self.navigationController?.pushViewController(AlertViewController(), animated: true)
    }
    
    //标签栏控制器
    @objc func JumpUITabBarController(){
        self.navigationController?.pushViewController(TabBarController(), animated: true)
    }
    
    //闭包传值
    @objc func JumpClosureFuncViewControl(){
        let mUILableViewControl = MVCViewController()
        //self.navigationController!.pushViewController(mUILableViewControl, animated:true)
        //dismiss 和 present 配对
        mUILableViewControl.closure = {(data:String) in
            print( "我是闭包传递的值过来" )
            print( "我是闭包传递的值过来:\(data)" )
            
        }
        self.present(  mUILableViewControl , animated: true, completion: nil)
        
    }
    //赋值传值
    @objc func JumpSearchViewControl(){
        let mUILableViewControl = SearchViewControl(data:"xiaobai")
        //self.navigationController!.pushViewController(mUILableViewControl, animated:true)
        //dismiss 和 present 配对
        mUILableViewControl.data = "搜索界面"
        
        self.present(  mUILableViewControl , animated: true, completion: nil)
        
    }
    //协议传值
    @objc func JumpProtocolViewControl(_ sender:AnyObject){
        let mMVCViewController = MVCViewController()
        mMVCViewController.delegate = self
        self.present(mMVCViewController, animated: true, completion: nil)
    }
    
    //跳转到UIlable
    @objc func JumpUILableViewControl(_ button:UIButton){
        let mUILableViewControl = UILableViewControl()
        self.navigationController!.pushViewController(mUILableViewControl, animated:true)
    }
    
    //点击事件
    @objc  func tapped(_ button:UIButton){
        print( "====" )
    }
    //选择器设置
    @objc func highlightBorder(_ sender: UIButton){
        // sender.isHidden = true
        sender.layer.borderColor = UIColor.red.cgColor
    }
    @objc func normalBorder(_ sender: UIButton){
        //sender.isHidden = false
        sender.layer.borderColor = UIColor.gray.cgColor
        
        //跳转到下个页面
        let secondViewController = Animation()
        self.navigationController!.pushViewController(secondViewController, animated:true)
    }
    
    //
    @objc func FuncUISwitch(_ button:UIButton){
        //跳转到下个页面
        let secondViewController = UISwitchViewController()
        self.navigationController!.pushViewController(secondViewController, animated:true)
    }
    //UIPageControl
    @objc func FuncUIPageControl(_ button:UIButton){
        
        let secondViewController = UIPageControlController()
        self.navigationController!.pushViewController(secondViewController, animated:true)
    }
    
    //UIInteractionControl ui交互控制
    @objc func UIInteractionControl(_ button:UIButton){
        //solid
        //let secondViewController = UIInteractionViewControl()
        //self.navigationController!.pushViewController(secondViewController, animated:true)
        
        //        let secondViewController = StoryUIViewController()
        //        self.navigationController!.pushViewController(secondViewController, animated:true)
        
        //performSegue(withIdentifier: "LoginToMain", sender: nil)
        //故事版
        
        var mUIStoryboard = UIStoryboard.init(name: "main", bundle: nil)
        var nav = mUIStoryboard.instantiateViewController(withIdentifier: "StoryUIViewController")
        
        self.navigationController?.pushViewController(nav, animated: true)
        
    }
    //活动指示器控件
    @objc func JumpUIActivityIndicatorView( _ button:UIButton ){
        let secondViewController = UIActivityIndicatorViewControl()
        self.navigationController!.pushViewController(secondViewController, animated:true)
    }
    //实例界面的切换和参数的传递
    @objc func JumpUISwitchViewControl(){
        let secondViewController = OneViewController()
        self.navigationController!.pushViewController(secondViewController, animated:true)
    }
    //ui导航试图控制
    @objc func JumpUINavigationViewControl(){
        self.navigationController!.pushViewController( TableViewController(), animated:true)
    }
    
    //viewControl 生命周期
    
    //加载试图调用
    override func loadView() {
        super.loadView()
        print( "加载视图调用" )
    }
    //加载试图完成时调用
    //viewDidLoad() 见顶部已经实现
    
    override func viewWillLayoutSubviews() {
        print( "将要布局子视图时调用的方法" )
    }
    override func viewDidLayoutSubviews() {
        print( "已经布局子视图调用的方法" )
    }
    override func viewWillAppear(_ animated: Bool) {
        print( "界面将要展现时调用的方法" )
    }
    override func viewDidAppear(_ animated: Bool) {
        print( "界面已经展示调用的方法" )
    }
    override func viewWillDisappear(_ animated: Bool) {
        print( "界面将要消失调用的方法" )
    }
    override func viewDidDisappear(_ animated: Bool) {
        print("界面已经消失调用的方法")
    }
    //    deinit{
    //        print( "析构函数，类销毁时候调用" )
    //    }
    override func didReceiveMemoryWarning() {
        print("收到内存警告的时候调用")
    }
    
    
    func dispatch_async_demo(){
        
        
        //函数回调
        //        loadSignature( {(string, error)->Void in
        //            print( string )
        //            print( error )
        //
        //        })
        
        //做完一件事才做下一件事情  串行
        //        do{
        //            if let signature = try loadSignature() {
        //                print( "signature=\(signature) ")
        //              addAppending(signature, to: "some data")
        //            }
        //            print(results)
        //        }catch{
        //            print( "error\(error)" )
        //        }
        Task{ //串行执行
            print( "开始" )
            do{
                _ = try await loadSignature2()
                print( "返回结果了1" )
            }catch{
                print( "error\(error)" )
            }
            print( "结束" )
            
            _ =  await loadSignature()
            print( "返回结果了2" )
        }
        
        //await Task.sleep( 1 ) 等待耗时
        
    }
    //声明为一步函数
    func loadSignature() async  -> String {
        //fatalError("暂未实现")
        return "1"
    }
    func loadSignature2() async throws -> String? {
        //等待
        try? await Task.sleep(nanoseconds:  2_000_000_000 )
        let (data, _) = try await URLSession.shared.data(from: URL(string: "https:baidu.com")! )
        return String(data: data, encoding: .utf8)
    }
    //并发编程
    func loadSignature(
        _ completion: @escaping (String?, Error?) -> Void
    )
    {
        DispatchQueue.global().async {
            do {
                //                let d = try Data(contentsOf: URL(string: //"https://www.baidu.com/")! )
                let d = "xiaobai"
                DispatchQueue.main.async {
                    completion( d, nil)
                }
            } catch {
                DispatchQueue.main.async {
                    completion(nil, error)
                }
                
            }
        }
    }
    
    var results: [String] = []
    func addAppending(_ value: String, to string: String) {
        results.append(value.appending(string))
    }
    
    // 从网络读取一个字符串 ，直接卡顿  同步等待
    func loadSignature() throws -> String? {
        // someURL 是远程 URL，比如 https://example.com
        let data = try Data(contentsOf: URL(string: "https://www.baidu.com/")!)
        return String(data: data, encoding: .utf8)
    }
    //循环处理某件事情 直到完毕
    func myFunction() {
        let array = ["xiaobai","nihao"]
        let group = DispatchGroup() // initialize
        
        array.forEach { obj in
            
            // Here is an example of an asynchronous request which use a callback
            group.enter() // wait
            //            LogoRequest.init().downloadImage(url: obj.url) { (data) in
            //                if (data) {
            //                    group.leave() // continue the loop
            //                }
            //            }
            group.leave() // continue the loop
            
        }
        
        group.notify(queue: .main) {
            print( "===" )
            // do something here when loop finished
        }
    }
    
    //同步方法
    func someSyncMethod() {
        addDrink()
        Task {
            await withThrowingTaskGroup(of: Void.self) { group in
                group.addTask {
                    try await self.loadResultRemotely()
                }
                group.addTask(priority: .low) {
                    try await self.processFromScratch()
                }
            }
            print("Done1: \(results)")
        }
        
        Task {
            await withThrowingTaskGroup(of: Void.self) { group in
                group.addTask {
                    try await self.loadResultRemotely()
                }
                group.addTask(priority: .low) {
                    try await self.processFromScratch()
                }
                do{
                    for try await f in group{
                        print( "f=\(f)" )
                        
                    }
                }catch{
                    print( "=====" )
                }
            }
            print("Done1: \(results)")
        }
        
        
    }
    
    //@MainActor 在主线程刷新
    @MainActor func loadResultRemotely() async throws {
        // 模拟网络加载的耗时
        await Task.sleep(2)
        results = ["data1^sig", "data2^sig", "data3^sig"]
    }
    
    func processFromScratch() async throws{
        await Task.sleep(2)
    }
    
    func holderFun(){
        Task {
            let holder = Holder()
            
            // holder.setResults([])
            await holder.setResults([])
            
            // holder.append(data.appending(signature))
            await holder.append("111")
            
            // print("Done: \(holder.getResults())")
            print("Done: \(await holder.results)")
        }
    }
    
    //同步函数
    func addDrink(){
        Task{
            await drinksUpdated()
            drinksUpdated2()
        }
    }
    func drinksUpdated() async {
        
    }
    func drinksUpdated2()  {
        
    }
    
    func download() async ->Data?{
        do{//
            let urlSessionTask: Wrapper<URLSessionTask?> = Wrapper(nil)
            let result: Data? =  try await withTaskCancellationHandler {
                try await withUnsafeThrowingContinuation { continuation in
                    urlSessionTask.value = URLSession.shared.dataTask(with: URL(string: "https://baidu.com")!) { data, _, error in
                        if let error = error {
                            continuation.resume(throwing: error)
                        } else {
                            continuation.resume(returning: data)
                        }
                    }
                    urlSessionTask.value?.resume()
                }
            } onCancel: {
                urlSessionTask.value?.cancel()
            }
            print( "====\(result)" )
            return result
        }catch{
            return nil
        }
        
        //aa.cancel()
    }
    
    func fetchLatestNews(completion: @escaping ([String]) -> Void) {
        DispatchQueue.main.async {
            completion(["Swift 5.5 release", "Apple acquires Apollo"])
        }
    }
    
    func fetchLatestNews() async -> [String] {
        //        return await withCheckedContinuation { continuation in // 相当于挂起点
        //            fetchLatestNews { items in
        //                continuation.resume(returning: items)   // 恢复
        //            }
        //        }
        //安全
        do{
            return try await withUnsafeThrowingContinuation { continuation in
                fetchLatestNews { items in
                    continuation.resume(returning: items)   // 恢复
                }
            }
        }catch{
            return []
        }
        
    }
    
    func printNews() async {
        let items = await fetchLatestNews()
        
        for item in items {
            print("printNews===\(item)")
        }
    }
    //队列
    func operationqueue(){
        let operation = BlockOperation(block: { [weak self] in
            self?.downloadImage()
            return
        })
        operation.completionBlock = {
            print( "执行完成" )
        }
        
        //创建一个NSOperationQueue实例并添加operation
        let queue = OperationQueue()
        queue.addOperation(operation)
        print(queue.operationCount)
    }
    func downloadImage(){
        print( "downloadImage" )
    }
}

extension String {
    
    func format(parameters: CVarArg...) -> String {
        return String(format: self, arguments: parameters)
    }
}
actor Holder {
    var results: [String] = []
    func setResults(_ results: [String]) {
        self.results = results
    }
    
    func append(_ value: String) {
        results.append(value)
    }
}
class Wrapper<Wrapped> {
    var value: Wrapped
    init(_ value: Wrapped) { self.value = value }
}

extension ViewController{
    //异步回调  Complete Handler(回调) 方式
    //    func processImageData2a(completionBlock: (_ result: Image?, _ error: Error?) -> Void) {
    //        loadWebResource("dataprofile.txt") { dataResource, error in
    //            guard let dataResource = dataResource else {
    //                completionBlock(nil, error)
    //                return
    //            }
    //            loadWebResource("imagedata.dat") { imageResource, error in // 2
    //                guard let imageResource = imageResource else {
    //                    completionBlock(nil, error)
    //                    return
    //                }
    //                decodeImage(dataResource, imageResource) { imageTmp, error in
    //                    guard let imageTmp = imageTmp else {
    //                        completionBlock(nil, error)
    //                        return
    //                    }
    //                    dewarpAndCleanupImage(imageTmp) { imageResult, error in
    //                        guard let imageResult = imageResult else {
    //                            completionBlock(nil, error)
    //                            return
    //                        }
    //                        completionBlock(imageResult)
    //                    }
    //                }
    //            }
    //        }
    //    }
}

extension ViewController{
    
    func test(){
        
        let date = Date()
        let currentTimeInterval = Int(date.timeIntervalSince1970)
        
        // 当前时间戳
        let currentDate =  formatter.date(from:"2022-05-01 11:11:11")
        let birthdayTimeInterval = Int(currentDate?.timeIntervalSince1970 ?? 0)
        
        
        print( "month=currentTimeInterval=\(currentTimeInterval)" )
        print( "month=birthdayTimeInterval=\(birthdayTimeInterval)" )
        
        let diffTimeInterval = currentTimeInterval - birthdayTimeInterval
        
        let monthTimeInterval = 30 * 24 * 3600
        
        let month = Float(diffTimeInterval)/Float(monthTimeInterval)
        
        
        print( "month=\(month)" )
        
        Task{
            await printMessage()
            await printAllWeatherReadings()
        }
        //队列打印
        var pQueue = Queue<String>()
        pQueue.enQueue("a")
        pQueue.enQueue("b")
        pQueue.enQueue("c")
        print(pQueue)
        pQueue.deQueue()
        print(pQueue.peek())
        print(pQueue)
        
        Task{
            let userProfile = UserProfile()
            await userProfile.loadData()
        }
        //错误处理
        //throw VendingMachineError.insufficientFunds(coinsNeeded: 5)
        do{
            throw try  VendingMachineError.insufficientFunds(coinsNeeded: 5)
        } catch VendingMachineError.insufficientFunds( let coinsNeeded ){
            print( "您抛出了 错误 coinsNeeded = \(coinsNeeded)" )
        }catch{
            print( "未匹配到错误类型" )
        }
        
        //顺序执行
        Task{
            //任务
            let photos = await listPhotos(inGallery: "name")
            print( "photos=1" )
            let firstPhoto = await downloadPhoto(name: photos[0])
            print( "photos=2" )
            let secondPhoto = await downloadPhoto(name: photos[1])
            print( "photos=3" )
            let thirdPhoto = await downloadPhoto(name: photos[2])
            print( "photos=4" )
            let photoRes = [firstPhoto, secondPhoto, thirdPhoto]
            print( "photos=5" )
            print(photoRes)
        }
        //加入任务组  乱序执行
        Task{
            await withTaskGroup(of: String.self) { group->Void in //group 没有返回类型
                let photos = await listPhotos(inGallery: "name")
                for name in photos {
                    group.addTask{
                        await self.downloadPhoto(name: name)//返回string
                    }
                }
                
                for await value in group {
                    print( "res=\(value)" )
                }
                //return 可以有返回值
            }
            
        }
        
        //循环请求
        //        可能存在方法中多次调用或者忘记调用completion的情况;
        //        闭包参数@escaping (String) -> Void难以阅读;
        //        层层嵌套的回调代码看起来很晦涩（所谓的回调地狱）;
        //        在swift5.0添加Result类型之前，使用completion handlers返回错误很困难;
        fetchWeatherHistory { [weak self] records in
            self?.calculateAverageTemperature(for: records) { average in
                self?.upload(result: average) { response in
                    print("Server response: \(response)")
                }
            }
        }
        //用并发实现 非任务组
        Task{
            let records = await fetchWeatherHistory2()
            let average = await calculateAverageTemperature2(for: records)
            let response = await upload2(result: average)
            print("Server response: \(response)")
        }
        //结构化并发
        Task{
            async let loadStrings = loadFromDatabase3()
            async let loadSignature = loadSignature3()
            
            let strings = await loadStrings
            let signature = await loadSignature
            if !signature.isEmpty {
                strings.forEach {
                    _results.append(String($0).appending(signature))
                }
            } else {
                //throw error
            }
            print("Server response: \(_results)")
        }
        
        //排序算法
        Rank.test()
        //异常扑捉
        catchClass.test()
        
        
    }
    
    func printMessage() async {
        print("printMessage====================")
        let string = await withTaskGroup(of: String.self) { group -> String in //group 表示有返回类型
            group.addTask {
                return "Hello"
            }
            group.addTask { "From" }
            group.addTask { "A" }
            group.addTask{ "Task" }
            group.addTask { "Group" }
            
            var collected = [String]()
            
            for await value in group {
                collected.append(value)
            }
            
            return collected.joined(separator: " ")
        }
        
        print(string)
    }
    func printAllWeatherReadings() async {
        do {
            print("Calculating average weather…")
            
            let result = try await withThrowingTaskGroup(of: [Double].self) { group -> String in
                group.async {
                    try await self.getWeatherReadings(fors: "London")
                }
                
                group.async {
                    try await self.getWeatherReadings(fors: "Rome")
                }
                
                group.async {
                    try await self.getWeatherReadings(fors: "San Francisco")
                }
                
                // 将所有的数组展平为单个数组
                let allValues = try await group.reduce([], +)
                print("数组! \(allValues)")
                
                // 计算平均值
                let average = allValues.reduce(0, +) / Double(allValues.count)
                return "平均温度为 \(average)"
            }
            
            print("完成! \(result)")
        } catch {
            print("计算数据时出错")
        }
    }
    func getWeatherReadings(fors:String) async ->[Double] {
        if fors == "London"{
            return [13.0]
        }else if fors == "Rome"{
            return [14.0]
        }
        
        return [12.0]
    }
    func listPhotos(inGallery name: String) async -> [String] {
        try? await Task.sleep(nanoseconds: 3 )  // Two seconds
        let result = ["1","2","3"]
        return result
    }
    func downloadPhoto(name:String) async ->String{
        try? await Task.sleep(nanoseconds: 1 )  // Two seconds
        return "name=\(name)"
    }
    
    
    //获取数据  异步  循环调用
    func fetchWeatherHistory(completion: @escaping ([Double]) -> Void) {
        // 用随机值来取代网络请求返回的数据
        DispatchQueue.global().async {
            let results = (1...100_000).map { _ in Double.random(in: -10...30) }
            completion(results)
        }
    }
    
    func calculateAverageTemperature(for records: [Double], completion: @escaping (Double) -> Void) {
        // 先求和再计算平均值
        DispatchQueue.global().async {
            let total = records.reduce(0, +)
            let average = total / Double(records.count)
            completion(average)
        }
    }
    
    func upload(result: Double, completion: @escaping (String) -> Void) {
        // 省略上传的网络请求代码，均返回"OK"
        DispatchQueue.global().async {
            completion("OK")
        }
    }
    
    //获取数据  异步
    func fetchWeatherHistory2() async->[Double] {
        try? await Task.sleep(nanoseconds:  2_000_000_000 )
        print( "结构化===fetchWeatherHistory2" )
        // 用随机值来取代网络请求返回的数据
        return (1...100_000).map { _ in Double.random(in: -10...30) }//返回可以省略
    }
    //获取平均值
    func calculateAverageTemperature2(for records: [Double]) async -> Double {
        print( "结构化===calculateAverageTemperature2" )
        // 先求和再计算平均值
        let total = records.reduce(0, +)
        let average = total / Double(records.count)
        return average
    }
    //上传数据
    func upload2(result: Double) async ->String {
        print( "结构化===upload2" )
        // 省略上传的网络请求代码，均返回"OK"
        return "ok"
    }
    
    func loadFromDatabase3()->String{
        return "loadFromDatabase"
    }
    func loadSignature3()->String{
        return "loadSignature"
    }
    
    //时间格式
    func timeFormat( time:String )->String{
        ///let time = "2022-05-01T22:00:00+08:00"
        //不是utc时间格式
        guard time.contains( "T" ) else{
            return time
        }
        let dateFormatter = DateFormatter.init()
        // UTC 时间格式
        dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss'+08:00'"
        let utcTimeZone = TimeZone(abbreviation: "UTC")
        dateFormatter.timeZone = utcTimeZone
        guard let dateFormatted = dateFormatter.date(from: time) else {
            return ""
        }
        // 输出时间字符串
        dateFormatter.timeZone = TimeZone.current
        dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
        return dateFormatter.string(from: dateFormatted)
    }
    
    //自定义弹框
    @objc func alertDialog(){
        //显示倒计时
        //设定定时时间为5s
        var countTime =  10
        continueButtonAction = "继续录制(\(countTime))"
        // 在global线程里创建一个时间源
        let codeTimer = DispatchSource.makeTimerSource(queue:DispatchQueue.global())
        // 设定这个时间源是每1秒循环一次，立即开始
        codeTimer.schedule(deadline: .now(), repeating: .milliseconds(1000))
        // 设定时间源的触发事件
        codeTimer.setEventHandler(handler: {
            // 主线程刷新UI
            //DispatchQueue.main.async {}
            countTime = countTime - 1
            self.continueButtonAction = "继续录制(\(countTime))"
            if self.uiAlertAction != nil {
                
                DispatchQueue.main.async {
                    self.uiAlertAction!.setValue( self.continueButtonAction , forKeyPath: "title")
                }
            }
            // 时间到了取消时间源
            if countTime <= 0{
                codeTimer.cancel()
                DispatchQueue.main.async {
                    self.uiAlertController?.dismiss(animated: true)
                }
                
            }
        })
        //启动定时器
        codeTimer.activate()
        
        DrawerDialog.init(title: "提示", message: "已经录制满1分钟了，是否现在上传？",style: .alert){ uiAlertController in
            self.uiAlertController = uiAlertController
        }.addAlertAction(title:continueButtonAction,handler: { action in
            //继续
            codeTimer.cancel()
            
        },returnAction: { action in
            self.uiAlertAction = action
        }).addAlertAction(title:"上传", handler: { action in
            codeTimer.cancel()
            
        } ,returnAction: { action in
           
        })
        
        
        
    }
    //跳转到swiftui
    @objc func jumpSwiftui(){
        
        let hostingController = UIHostingController(rootView: SwiftUIView1())
        navigationController?.pushViewController(hostingController, animated: true)
        
    }
    
}
